package com.igl.talk.android.client.core.service;/*
 * @author Adam Wieczorek 
 *
 * 16/03/2014
 *
 * All rights reserved.
 */

import android.content.ComponentName;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
import android.widget.ArrayAdapter;
import com.igl.talk.android.client.core.handlers.ClientHandler;
import com.igl.talk.android.client.core.handlers.HandlerInteface;
import com.igl.talk.android.client.core.model.MessageModel;
import com.igl.talk.android.client.ide.models.IdeMessageModel;

import java.util.ArrayList;
import java.util.List;

public enum Server implements ServerApi, HandlerInteface {

    INSTANCE;

    // Service related variables
    private final Messenger messenger = new Messenger(ClientHandler.getInstance());
    private final String LOG_TAG = Server.class.getSimpleName() + ".class";
    private ArrayAdapter<?> viewAdapter;

    private Messenger service = null;

    private boolean connected = false;

    private List<MessageModel> messages = new ArrayList<>();

    private final ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName className, IBinder service) {
            if (Server.this.service == null) {
                Server.this.service = new Messenger(service);
            }
            Server.this.connected = true;
            Log.d(LOG_TAG, "SERVICE CONNECTED");
            try {
                Message androidMessage = Message.obtain(null, MSG_MAKE_SERVICE_CLIENT_IPC);
                androidMessage.replyTo = messenger;
                Server.this.service.send(androidMessage);
            } catch (RemoteException e) {
                Log.e(LOG_TAG, "Connection error");
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName className) {
            Log.d(LOG_TAG, "SERVICE DISCONNECTED");
            service = null;
            connected = false;
        }
    };

    Server() {
        ClientHandler.getInstance().setMessages(messages);
    }

    @Override
    public boolean register(String username) {
        if (!connected) {
            Log.d(LOG_TAG, "Not connected");
            return false;
        }
        Message msg = Message.obtain(null, MSG_REGISTER_NEW_USER, 0, 0);
        msg.obj = username;
        try {
            service.send(msg);
            return true;
        } catch (RemoteException e) {
            Log.e(LOG_TAG, "Connection error");
        }
        return false;
    }

    @Override
    public List<IdeMessageModel> getMessages(int index1, int index2) {
        return null;
    }

    @Override
    public boolean sendMessage(IdeMessageModel message) {
        if (!connected) {
            Log.e(LOG_TAG, "Not connected");
            return false;
        }
        MessageModel coreMessageModel = new MessageModel(message.getUserName(), message.getMessage());
        Message androidMessage = Message.obtain(null, MSG_SEND_MESSAGE, 0, 0);
        androidMessage.obj = coreMessageModel;
        try {
            service.send(androidMessage);
            return true;
        } catch (RemoteException e) {
            Log.e(LOG_TAG, "Connection error");
        }
        return false;
    }

    @Override
    public boolean logout() {
        if (!connected) {
            return false;
        }
        Message msg = Message.obtain(null, MSG_LOGOUT, 0, 0);
        try {
            service.send(msg);
            return true;
        } catch (RemoteException e) {
            Log.e(LOG_TAG, "Connection error");
        }
        return false;
    }

    @Override
    public ServiceConnection getConnection() {
        return connection;
    }

    @Override
    public boolean isConnectionActive() {
        return connected;
    }

    @Override
    public void closeConnection() {
        connected = false;
    }
}
